home *** CD-ROM | disk | FTP | other *** search
-
- /*
- * Vogl/Vogle driver for Sun using sunview.
- *
- */
- /*
- * define VOGLE for VOGLE library or leave blank for VOGL library
- #define VOGLE 1
- */
- #undef VOGLE
-
- #include <stdio.h>
-
- #include <suntool/sunview.h>
- #include <suntool/canvas.h>
- #include <fcntl.h>
- #include <errno.h>
-
- #ifdef SUN_3_5
- #define event_action event_id
- #endif
-
- #ifdef VOGLE
- #include "vogle.h"
- #else
- #include "vogl.h"
- #endif
-
- #define CMAPSIZE 256
- #define STDFONTDIR "/usr/lib/fonts/fixedwidthfonts/"
-
- #define MIN(x,y) ((x) < (y) ? (x) : (y))
-
- #define OP_WHITE (PIX_SRC | PIX_COLOR(7) | PIX_DONTCLIP)
- #define OP_BLACK (PIX_SRC | PIX_COLOR(0) | PIX_DONTCLIP)
- #define COL_WHITE 7
- #define COL_BLACK 0
-
- static Pixwin *pw_tmp, *pw;
-
- #ifdef BASE_COL_SET
- static Pixwin *pw0;
- #endif
-
- static Pixrect *backb;
- static Pixfont *font_id;
- static int wfd, blanket_win;
- static int oldflags;
- static int pwfd, h, w;
- static int colour;
- static Rect wrect;
-
- static char use_sunview_canvas = 0;
-
- #define DASHED 1
- #define FATLINES 2
- static unsigned char lineflags = 0;
-
- static Pr_brush brush = {1};
- static Pr_texture *t = (Pr_texture *)NULL;
- static Pr_texture tex = {
- (short *)NULL,
- 0,
- {1, 1, 1, 0},
- 0,
- };
-
- /*
- * default colour map
- */
-
- static int colnum = 8;
- static u_char red[CMAPSIZE] = {
- 0, 255, 0, 255, 0, 255, 0, 255, 0,
- },
- green[CMAPSIZE] = {
- 0, 0, 255, 255, 0, 0, 255, 255, 0,
- },
- blue[CMAPSIZE] = {
- 0, 0, 0, 0, 255, 255, 255, 255, 0,
- };
-
- /*
- * redisplay
- *
- * redisplay the window.
- */
- static void redisplay(void)
- {
- pw_damaged(pw);
-
- pw_repairretained(pw);
-
- pw_donedamaged(pw);
- }
-
- /*
- * To be called from a resize procedure from withing sunview
- */
- int vo_sunview_canvas_size(
- int sw,
- int sh)
- {
- w = sw;
- h = sh;
-
- vdevice.sizeX = vdevice.sizeY = MIN(h, w);
- vdevice.sizeSx = w;
- vdevice.sizeSy = h;
-
- if (pw->pw_prretained) {
- mem_destroy(pw->pw_prretained);
- backb = pw->pw_prretained = mem_create(w, h, vdevice.depth);
- }
- }
-
- /*
- * vo_sunview_canvas
- *
- * Tells VOGLE/VOGL to use a supplied sunview pixwin
- */
- int vo_sunview_canvas(
- Canvas canvas,
- int cw,
- int ch)
- {
- pw = canvas_pixwin(canvas);
- use_sunview_canvas = 1;
-
- w = cw;
- h = ch;
-
- vdevice.sizeX = vdevice.sizeY = MIN(h, w);
- vdevice.sizeSx = w;
- vdevice.sizeSy = h;
-
- vdevice.depth = pw->pw_pixrect->pr_depth;
- if (!pw->pw_prretained) /* Make us retained */
- backb = pw->pw_prretained = mem_create(w, h, vdevice.depth);
-
- /*
- * Set up the color map.
- */
-
- if (vdevice.depth > 1) {
- pw_setcmsname(pw, "vogle");
- pw_putcolormap(pw, 0, colnum, red, green, blue);
- }
-
- wfd = (int)window_get(canvas, WIN_FD);
-
- /*
- * Set non-blocking input for window.
- oldflags = fcntl(wfd, F_GETFL, 0);
- if (fcntl(wfd, F_SETFL, FNDELAY) < 0) {
- perror("F_SETFL");
- exit(1);
- }
- */
-
-
- pw_batch_on(pw);
-
- #ifndef VOGLE
- vdevice.devname = "sun";
- #endif
-
- return(1);
- }
-
- /*
- * SUN_init
- *
- * initialises drawing canvas to occupy current window
- */
- int SUN_init(void)
- {
- int i, prefx, prefy, prefxs, prefys, bw;
- char name[WIN_NAMESIZE];
- Inputmask imk, imp;
- int rootfd;
-
- if (use_sunview_canvas)
- return(1);
-
- pw = (Pixwin *)NULL;
-
- #ifdef BASE_COL_SET
- pw0 = pw;
- #endif
-
- /*
- * get the gfx win so we have some default sizes to use
- */
- we_getgfxwindow(name);
- pwfd = open(name, 2);
- win_getrect(pwfd, &wrect);
-
- /*
- * Get the input masks of the base window...
- */
- win_get_pick_mask(pwfd, &imp);
- win_get_kbd_mask(pwfd, &imk);
-
-
- /*
- * get a new window (either going to be a blanket window or
- * a window in it's own right)
- */
- if ((wfd = win_getnewwindow()) == -1) {
- fprintf(stderr, "No new windows!\n");
- exit(1);
- }
-
- getprefposandsize(&prefx, &prefy, &prefxs, &prefys);
-
- if (prefx > -1) {
- wrect.r_left = prefx;
- wrect.r_top = prefy;
- }
-
- if (prefxs > -1) {
- wrect.r_width = prefxs;
- wrect.r_height = prefys;
- }
-
- w = wrect.r_width;
- h = wrect.r_height;
-
- bw = 3;
- if (prefx > -1 || prefxs > -1) {
- /*
- * Make room for a 3 pixel border
- */
- if (wrect.r_left <= 2)
- wrect.r_left = 0;
- else
- wrect.r_left -= bw;
-
- if (wrect.r_top <= 2)
- wrect.r_top = 0;
- else
- wrect.r_top -= bw;
-
- wrect.r_width += 2 * bw;
- wrect.r_height += 2 * bw;
-
- win_setrect(wfd, &wrect);
-
- /*
- * get the parent (probably full screen window)
- * so we can size our window to any size we like
- * on the screen.
- */
- we_getparentwindow(name);
- rootfd = open(name, 2);
-
- win_setlink(wfd, WL_PARENT, win_fdtonumber(rootfd));
- win_setlink(wfd, WL_COVERED, WIN_NULLLINK);
- win_insert(wfd);
-
- wmgr_top(wfd, rootfd);
-
- pw = pw_open(wfd);
-
- #ifdef BASE_COL_SET
- /*
- * Get the pixrect for the window that we started in
- * so we can set it's colourmap as well
- */
- pw0 = pw_open(pwfd);
- #endif
-
- close(rootfd);
- blanket_win = 0;
- } else {
- win_insertblanket(wfd, pwfd);
- pw = pw_region(pw_open(wfd), 0, 0, w, h);
- blanket_win = 1;
- }
-
- /*
- * Set non-blocking input for window.
- */
- oldflags = fcntl(wfd, F_GETFL, 0);
- if (fcntl(wfd, F_SETFL, FNDELAY) < 0) {
- perror("F_SETFL");
- exit(1);
- }
-
- /*
- * Setup the input masks for window.
- */
-
- win_set_kbd_mask(wfd, &imk);
- win_set_pick_mask(wfd, &imp);
-
- vdevice.depth = pw->pw_pixrect->pr_depth;
-
- /*
- * Set up the color map.
- */
-
- if (vdevice.depth > 1) {
- pw_setcmsname(pw, "vogle");
- pw_putcolormap(pw, 0, colnum, red, green, blue);
- #ifdef BASE_COL_SET
- if (pw0 != (Pixwin *)NULL) {
- pw_setcmsname(pw0, "vogle");
- pw_putcolormap(pw0, 0, colnum, red, green, blue);
- }
- #endif
- }
-
- if (prefx > -1 || prefxs > -1) {
- /*
- * Draw the border...
- */
- int x0, y0, x1, y1;
-
- x0 = y0 = 0;
- x1 = wrect.r_width - 1;
- y1 = 0;
- pw_vector(pw, x0, y0, x1, y1, OP_WHITE, COL_WHITE);
- pw_vector(pw, x0 + 2, y0 + 2, x1 - 2, y1 + 2, OP_WHITE, COL_WHITE);
- pw_vector(pw, x0 + 1, y0 + 1, x1 - 1, y1 + 1, OP_BLACK, COL_BLACK);
- x0 = x1;
- y0 = y1;
- x1 = x0;
- y1 = wrect.r_height - 1;
- pw_vector(pw, x0, y0, x1, y1, OP_WHITE, COL_WHITE);
- pw_vector(pw, x0 - 2, y0 + 2, x1 - 2, y1 - 2, OP_WHITE, COL_WHITE);
- pw_vector(pw, x0 - 1, y0 + 1, x1 - 1, y1 - 1, OP_BLACK, COL_BLACK);
- x0 = x1;
- y0 = y1;
- x1 = 0;
- y1 = wrect.r_height - 1;
- pw_vector(pw, x0, y0, x1, y1, OP_WHITE, COL_WHITE);
- pw_vector(pw, x0 - 2, y0 - 2, x1 + 2, y1 - 2, OP_WHITE, COL_WHITE);
- pw_vector(pw, x0 - 1, y0 - 1, x1 + 1, y1 - 1, OP_BLACK, COL_BLACK);
- x0 = x1;
- y0 = y1;
- x1 = 0;
- y1 = 0;
- pw_vector(pw, x0, y0, x1, y1, OP_WHITE, COL_WHITE);
- pw_vector(pw, x0 + 2, y0 - 2, x1 + 2, y1 + 2, OP_WHITE, COL_WHITE);
- pw_vector(pw, x0 + 1, y0 - 1, x1 + 1, y1 + 1, OP_BLACK, COL_BLACK);
- pw_tmp = pw;
- pw = pw_region(pw_tmp, 3, 3, w, h);
- pw_close(pw_tmp);
- }
-
-
- backb = pw->pw_prretained = mem_create(w, h, vdevice.depth);
-
- signal(SIGWINCH, redisplay);
-
- /*
- * Let VOGLE/VOGL know about the window size.
- */
- vdevice.sizeX = vdevice.sizeY = MIN(w, h);
- vdevice.sizeSx = w;
- vdevice.sizeSy = h;
-
- /*
- * Set up batching.....(for speed and "pseudo" double buffering)
- */
- pw_batch_on(pw);
-
- return(1);
- }
-
- /*
- * SUN_exit
- *
- * cleans up before returning the window to normal.
- */
- int SUN_exit(void)
- {
- long nbytes;
- int i;
- Event event;
-
- if (use_sunview_canvas)
- return(1);
-
- /*
- * Flush all events for this window.
- *
- * While doing non-blocking input input_readevent returns -1 and
- * errno == EWOULDBLOCK when everything has been read, so if
- * errno != EWOULDBLOCK then something naughty happened...
- */
- while (input_readevent(wfd, &event) >= 0)
- ;
-
- if (errno != EWOULDBLOCK) {
- perror("SUN_exit(flushing), input_readevent");
- exit();
- }
-
- /*
- * reset wfd to blocking input.
- */
- if (fcntl(wfd, F_SETFL, oldflags) < 0) {
- perror("oldflags, F_SETFL");
- exit(1);
- }
-
- if (blanket_win)
- win_removeblanket(wfd);
- else
- win_remove(wfd);
-
- signal(SIGWINCH, SIG_DFL);
-
- return(1);
- }
-
- /*
- * SUN_draw
- *
- * draws a line from the current graphics position to (x, y).
- *
- * Note: (0, 0) is defined as the top left of the window on a sun (easy
- * to forget).
- */
- int SUN_draw(
- int x,
- int y)
- {
- if (!lineflags) /* If thin and solid */
- pw_vector(pw, vdevice.cpVx, vdevice.sizeSy - vdevice.cpVy, x, vdevice.sizeSy - y, PIX_SRC | PIX_COLOR(colour), colour);
- else /* Fat and/or dashed */
- pw_line(pw, vdevice.cpVx, vdevice.sizeSy - vdevice.cpVy, x, vdevice.sizeSy - y, &brush, t, PIX_SRC | PIX_COLOR(colour));
-
- if (vdevice.sync)
- pw_show(pw);
- }
-
- /*
- * SUN_getkey
- *
- * grab a character from the keyboard.
- */
- int SUN_getkey(void)
- {
- Event event;
-
- pw_show(pw);
-
- do {
- while ((input_readevent(wfd, &event) < 0) && (errno == EWOULDBLOCK))
- ; /* Nothing to read - wait for something */
-
- } while (!event_is_ascii(&event)); /* Wait for a key press */
-
- return(event_action(&event));
- }
-
- /*
- * SUN_checkkey
- *
- * Check if a keyboard key has been hit. If so return it.
- */
- static Event *saved_event;
-
- int SUN_checkkey(void)
- {
- static Event event;
-
- if(saved_event == &event)
- saved_event = NULL;
-
- if (saved_event && event_is_ascii(saved_event)) {
- Event *tmp = saved_event;
-
- saved_event = NULL;
- return(event_action(tmp));
- }
-
- saved_event = NULL;
-
- if (input_readevent(wfd, &event) < 0) {
- if (errno == EWOULDBLOCK) {
- return(0);
- } else {
- perror("SUN_checkkey, input_readevent");
- exit(1);
- }
- } else if (event_is_ascii(&event))
- return(event_action(&event));
- else
- saved_event = &event;
-
- return(0);
- }
-
-
- /*
- * SUN_locator
- *
- * return the window location of the cursor, plus which mouse button,
- * if any, is been pressed.
- */
- int SUN_locator(
- int *wx,
- int *wy)
- {
- int but;
- static Event event;
-
- if (vdevice.sync)
- pw_show(pw);
-
- but = 0;
-
- *wx = win_get_vuid_value(wfd, LOC_X_ABSOLUTE);
- *wy = (int)vdevice.sizeSy - win_get_vuid_value(wfd, LOC_Y_ABSOLUTE);
-
- /* This used to work under 4.0 but not longer ..... Maybe
- * SUN don't want us to use sunview anymore?
- */
- if (win_get_vuid_value(wfd, BUT(1)))
- but |= 1;
-
- if (win_get_vuid_value(wfd, BUT(2)))
- but |= 2;
-
- if (win_get_vuid_value(wfd, BUT(3)))
- but |= 3;
-
-
- if (use_sunview_canvas)
- return(but);
-
- if (saved_event == &event) /*Don't Re-use a previously rejected event*/
- saved_event = NULL;
-
- if (saved_event && event_is_button(saved_event) && event_is_down(saved_event)) {
- if (event_action(saved_event) == MS_LEFT)
- but |= 1;
- if (event_action(saved_event) == MS_MIDDLE)
- but |= 2;
- if (event_action(saved_event) == MS_RIGHT)
- but |= 4;
-
- saved_event = NULL;
- return(but);
- }
-
-
- if (input_readevent(wfd, &event) < 0) {
- if (errno == EWOULDBLOCK) {
- return(0);
- } else {
- perror("SUN_locator, input_readevent");
- exit(1);
- }
- } else if (event_is_button(&event) && event_is_down(&event)) {
- if (event_action(&event) == MS_LEFT)
- but |= 1;
- if (event_action(&event) == MS_MIDDLE)
- but |= 2;
- if (event_action(&event) == MS_RIGHT)
- but |= 4;
- } else
- saved_event = &event;
-
- return(but);
- }
-
- #ifdef VOGLE
- /*
- * SUN_clear
- *
- * Clear the screen to current colour
- */
- int SUN_clear(void)
- {
- pw_writebackground(pw, 0, 0, w, h, PIX_SRC | PIX_COLOR(colour) | PIX_DONTCLIP);
-
- if (vdevice.sync)
- pw_show(pw);
- }
-
- #else
-
- /*
- * SUN_clear
- *
- * Clear the viewport to current colour
- */
- int SUN_clear(void)
- {
- unsigned int vw = vdevice.maxVx - vdevice.minVx;
- unsigned int vh = vdevice.maxVy - vdevice.minVy;
-
- pw_writebackground(pw,
- vdevice.minVx, vdevice.sizeSy - vdevice.maxVy,
- vw, vh,
- PIX_SRC | PIX_COLOR(colour) | PIX_DONTCLIP
- );
-
- if (vdevice.sync)
- pw_show(pw);
- }
-
- #endif
-
- /*
- * SUN_color
- *
- * set the current drawing color index.
- */
- int SUN_color(int ind)
- {
- colour = ind;
- }
-
- /*
- * SUN_mapcolor
- *
- * change index i in the color map to the appropriate r, g, b, value.
- */
- int SUN_mapcolor(
- int i,
- int r,
- int g,
- int b)
- {
- int j;
-
- if (i >= 255 || vdevice.depth == 1)
- return(-1);
-
- if (i >= colnum)
- colnum = i;
-
- red[i] = r;
- green[i] = g;
- blue[i] = b;
-
- red[255] = (u_char)~red[0];
- green[255] = (u_char)~green[0];
- blue[255] = (u_char)~blue[0];
-
- pw_putcolormap(pw, 0, colnum, red, green, blue);
- #ifdef BASE_COL_SET
- pw_putcolormap(pw0, 0, colnum, red, green, blue);
- #endif
- }
-
- /*
- * SUN_font
- *
- * Set up a hardware font. Return 1 on success 0 otherwise.
- *
- */
- int SUN_font(char *fontfile)
- {
- char name[BUFSIZ];
-
- if (font_id != (Pixfont *)NULL)
- pf_close(font_id);
-
- if ((font_id = pf_open(fontfile)) == NULL)
- if (*fontfile != '/') {
- strcpy(name, STDFONTDIR);
- strcat(name, fontfile);
- if ((font_id = pf_open(name)) == NULL)
- return(0);
- } else
- return(0);
-
- vdevice.hheight = font_id->pf_defaultsize.y;
- vdevice.hwidth = font_id->pf_defaultsize.x;
-
- return(1);
- }
-
- /*
- * SUN_char
- *
- * outputs one char - is more complicated for other devices
- */
- int SUN_char(char c)
- {
- char *s = " ";
-
- s[0] = c;
- pw_ttext(pw, vdevice.cpVx, (int)(vdevice.sizeSy - vdevice.cpVy), PIX_SRC | PIX_COLOR(colour), font_id, s);
-
- if (vdevice.sync)
- pw_show(pw);
- }
-
- /*
- * SUN_string
- *
- * Display a string at the current drawing position.
- */
- int SUN_string(char s[])
- {
- pw_ttext(pw, vdevice.cpVx, (int)(vdevice.sizeSy - vdevice.cpVy), PIX_SRC | PIX_COLOR(colour), font_id, s);
-
- if (vdevice.sync)
- pw_show(pw);
- }
-
- /*
- * SUN_fill
- *
- * fill a polygon
- */
- int SUN_fill(
- int n,
- int x[],
- int y[])
- {
- struct pr_pos vlist[128];
- int i, npnts;
-
- if (n > 128)
- verror("vogle: more than 128 points in a polygon");
-
- npnts = n;
-
- for (i = 0; i < n; i++) {
- vlist[i].x = x[i];
- vlist[i].y = vdevice.sizeSy - y[i];
- }
-
- pw_polygon_2(pw, 0, 0, 1, &npnts, vlist, PIX_SRC | PIX_COLOR(colour) | PIX_DONTCLIP, (Pixwin *)NULL, 0, 0);
-
- vdevice.cpVx = x[n-1];
- vdevice.cpVy = y[n-1];
-
- /*
- if (vdevice.sync)
- pw_show(pw);
- */
- }
-
- /*
- * SUN_backb
- *
- * swap to memory only drawing (backbuffer) - a little slow but it
- * works on everything.
- */
- int SUN_backb(void)
- {
- /*
- * Batching is already on....
- */
- return(0);
- }
-
- /*
- * SUN_swapb
- *
- * swap the front and back buffers.
- */
- int SUN_swapb(void)
- {
- if (vdevice.inbackbuffer)
- pw_show(pw);
-
- return(0);
- }
-
- /*
- * SUN_frontb
- *
- * draw in the front buffer
- */
- int SUN_frontb(void)
- {
- /*
- * Make it visible anyway....
- */
- pw_show(pw);
- }
-
- /*
- * SUN_sync
- *
- * Syncronise the display with what we thing has been output
- */
- int SUN_sync(void)
- {
- pw_show(pw);
- }
-
- /*
- * SUN_setls
- *
- * Set the line style....
- */
- int SUN_setls(int lss)
- {
-
- unsigned ls = lss;
- static short dashes[17];
-
- int i, n, a, b, offset;
-
- if (ls == 0xffff) {
- lineflags &= ~DASHED;
- t = (Pr_texture *)NULL;
- return;
- }
-
- lineflags |= DASHED;
-
- for (i = 0; i < 16; i++)
- dashes[i] = 0;
-
- for (i = 0; i < 16; i++) /* Over 16 bits */
- if ((ls & (1 << i)))
- break;
-
- offset = i;
-
- #define ON 1
- #define OFF 0
-
- a = b = OFF;
- if (ls & (1 << 0))
- a = b = ON;
-
- n = 0;
- for (i = 0; i < 16; i++) { /* Over 16 bits */
- if (ls & (1 << i))
- a = ON;
- else
- a = OFF;
-
- if (a != b) {
- b = a;
- n++;
- }
- dashes[n]++;
- }
- n++;
- dashes[n] = 0;
-
- tex.pattern = &dashes[0];
- tex.offset = offset;
- t = &tex;
- }
-
- /*
- * SUN_setlw
- *
- * Set the line style....
- */
- int SUN_setlw(int lw)
- {
- if (lw > 1) {
- lineflags |= FATLINES;
- brush.width = lw;
- } else
- lineflags &= ~FATLINES;
- }
-
- /*
- * the device entry
- */
- static DevEntry sundev = {
- "sun",
- "screen.b.16",
- "screen.b.12",
- SUN_backb,
- SUN_char,
- SUN_checkkey,
- SUN_clear,
- SUN_color,
- SUN_draw,
- SUN_exit,
- SUN_fill,
- SUN_font,
- SUN_frontb,
- SUN_getkey,
- SUN_init,
- SUN_locator,
- SUN_mapcolor,
- #ifndef VOGLE
- SUN_setls,
- SUN_setlw,
- #endif
- SUN_string,
- SUN_swapb,
- SUN_sync
- };
-
- /*
- * _SUN_devcpy
- *
- * copy the sun device into vdevice.dev.
- */
- int _SUN_devcpy(void)
- {
- vdevice.dev = sundev;
- }
-